/**
 * @名称: tabs of jquery
 * @更新: 2017.12.1
 * @作者: yuguoliang
 * @博客：http://www.cssw3c.com
 */
;(function($){

    var effects = {
        // simple "toggle" effect
        'default': function(i, done) {
            this.getPanes().hide().eq(i).show();
            done.call();
        },

        /*
         configuration:
         - fadeOutSpeed (positive value does "crossfading")
         - fadeInSpeed
         */
        fade: function(i, done) {

            var conf = this.getConf(),
                speed = conf.fadeOutSpeed,
                panes = this.getPanes();

            if (speed) {
                panes.fadeOut(speed);
            } else {
                panes.hide();
            }

            panes.eq(i).fadeIn(conf.fadeInSpeed, done);
        },

        // for basic accordions
        slide: function(i, done) {
            var conf = this.getConf();
            this.getPanes().slideUp(conf.slideUpSpeed);
            this.getPanes().eq(i).slideDown(conf.slideDownSpeed, done);
        },

        /**
         * AJAX effect
         */
        ajax: function(i, done)  {
            this.getPanes().eq(0).load(this.getTabs().eq(i).attr("href"), done);
        }
    };

    function Tabs(root, paneSelector, conf) {

        var self = this,
            trigger = root.add(this),
            tabs = root.find(conf.tabs),
            panes = paneSelector.jquery ? paneSelector : root.children(paneSelector),
            current;
        // make sure tabs and panes are found
        if (!tabs.length)  { tabs = root.children(); }
        if (!panes.length) { panes = root.parent().find(paneSelector); }
        if (!panes.length) { panes = $(paneSelector); }


        // public methods
        $.extend(this, {
            click: function(i, e) {
                var tab = tabs.eq(i);

                if (typeof i == 'string' && i.replace("#", "")) {
                    tab = tabs.filter("[href*=\"" + i.replace("#", "") + "\"]");
                    i = Math.max(tabs.index(tab), 0);
                }

                if (conf.rotate) {
                    var last = tabs.length -1;
                    if (i < 0) { return self.click(last, e); }
                    if (i > last) { return self.click(0, e); }
                }

                if (!tab.length) {
                    if (current >= 0) { return self; }
                    i = conf.initialIndex;
                    tab = tabs.eq(i);
                }

                //是否开放模式，改模式下click事件自己写
                if(!conf.development){
                    // current tab is being clicked
                    if (i === current) { return self; }
                }


                // possibility to cancel click action
                e = e || $.Event();
                e.type = "onBeforeClick";
                trigger.trigger(e, [i]);
                if (e.isDefaultPrevented()) { return; }

                var effect = conf.effect;

                // call the effect
                effects[effect].call(self, i, function() {
                    current = i;
                    // onClick callback
                    e.type = "onClick";
                    trigger.trigger(e, [i]);
                });

                if(!conf.development){
                    // default behaviour
                    tabs.removeClass(conf.current);
                    tab.addClass(conf.current);
                }

                return self;
            },

            getConf: function() {
                return conf;
            },

            getTabs: function() {
                return tabs;
            },

            getPanes: function() {
                return panes;
            },

            getCurrentPane: function() {
                return panes.eq(current);
            },

            getCurrentTab: function() {
                return tabs.eq(current);
            },

            getIndex: function() {
                return current;
            },

            next: function() {
                return self.click(current + 1);
            },

            prev: function() {
                return self.click(current - 1);
            },

            destroy: function() {
                tabs.off(conf.event).removeClass(conf.current);
                panes.find("a[href^=\"#\"]").off("click.T");
                return self;
            }

        });

        // callbacks
        $.each("onBeforeClick,onClick".split(","), function(i, name) {

            // configuration
            if ($.isFunction(conf[name])) {
                $(self).on(name, conf[name]);
            }

            // API
            self[name] = function(fn) {
                if (fn) { $(self).on(name, fn); }
                return self;
            };
        });


        // setup click actions for each tab
        tabs.each(function(i) {
            $(this).on(conf.event, function(e) {
                self.click(i, e);
                return e.preventDefault();
            });
        });

        // cross tab anchor link
        panes.find("a[href^=\"#\"]").on("click.T", function(e) {
            self.click($(this).attr("href"), e);
        });

        // open initial tab
        if (location.hash && conf.tabs == "a" && root.find("[href=\"" +location.hash+ "\"]").length) {
            self.click(location.hash);
        } else {
            if (conf.initialIndex === 0 || conf.initialIndex > 0) {
                self.click(conf.initialIndex);
            }
        }
    }

	$.fn.tabs = function(paneSelector,conf){
		var defaults = {
			tabs: 'a',
			current: 'current',
            onBeforeClick: null,
            onClick: null,
            effect: 'default',
            initialIndex: 0,
            event: 'click',

            //添加参数支持自定义开发，防止选中后再次点击没有反应情况
            //通常搭配initialIndex：-1使用
            development:false,

            // slide effect
            slideUpSpeed: 400,
            slideDownSpeed: 400,
		};

        var el = this.data("tabs");
        if (el) {
            el.destroy();
            this.removeData("tabs");
        }

        if ($.isFunction(conf)) {
            conf = {onBeforeClick: conf};
        }

        // setup conf
        conf = $.extend({}, defaults, conf);

        this.each(function() {
            el = new Tabs($(this), paneSelector, conf);
            $(this).data("tabs", el);
        });

        return conf.api ? el: this;
    };

})(jQuery);